#include "memory.h"

namespace MemorySpace
{
	//private
	void memory::create_players(int num_players){
		string name;
		for (int i = 0; i < num_players; i++)
		{
			cout << "Enter Names (Player " << i + 1 << "): ";
			cin >> name;
			pv.push_back(player(name));
		}
		currentPlayer = 0;
	}

	void memory::create_board(int r, int c){
		srand(time(NULL));
		//create rows
		cvv = new vector<vector<card>>(r);

		//check if board has even amount of cards
		if ((r*c) % 2 != 0)
			//if not, remove 1 column
			c -= 1;

		//create columns
		for (int i = 0; i < r; i++)
		{
			(*cvv)[i] = vector<card>(c);
		}

		//create vector of card values
		vector<char> vc;
		char ch = 'A';
		for (int i = 0; i < r*c; i++){
			vc.push_back(ch);
			if (i % 2 == 1){
				ch++;
			}
		}
		//shuffle card values
		random_shuffle(vc.begin(), vc.end());
		
		//add cards with the randomized values to vector
		int k = 0;
		for (int i = 0; i < r; i++){
			for (int j = 0; j < c; j++)
			{
				(*cvv)[i][j] = card(vc[k]);
				k++;
			}
		}
	}



	//public
	void memory::draw()
	{
		system("cls");
		for (int i = 0; i < (*cvv).size() ; i++)
		{
			//print line div |==============|
			cout << "|";
			for (int j = 0; j < (*cvv)[0].size() * 4 - 1; j++)
			{
				cout << "=";
			}
			cout << "|" << endl;

			//print cards, separated by " | "
			cout << "|";
			for (int j = 0; j < (*cvv)[i].size(); j++)
			{
				cout << " ";
				if ((*cvv)[i][j].isTaken())
					cout << " ";
				else if ((*cvv)[i][j].isFlipped())
					cout << (*cvv)[i][j].getSymbol();
				else
					cout << "?";
				cout << " |";
			}
			cout << endl;
		}

		//print final line div
		cout << "|";
		for (int j = 0; j < (*cvv)[0].size() * 4 - 1; j++)
		{
			cout << "=";
		}
		cout << "|" << endl;

		Console::gotoxy(0, (*cvv).size() + 5);
		cout << "Current Player: " << pv[currentPlayer].getName();

		Console::gotoxy(0, (*cvv).size() + 7);
		cout << "Scores";
		for (int i = 0; i < pv.size(); i++)
		{
			Console::gotoxy(0, (*cvv).size() + 8 + i);
			cout << left << setw(10) << pv[i].getName() << setw(5) << pv[i].getScore();
		}
	}

	void memory::play()
	{
		int x = 0;
		int y = 0;
		currentPlayer = 0;
		bool playing = true;
		vector<card*> shownCards;			//amount of cards that current player has selected

		const char KEY_LEFT = 75;
		const char KEY_RIGHT = 77;
		const char KEY_UP = 72;
		const char KEY_DOWN = 80;
		const char KEY_ENTER = 13;

		Console::setcursor(1, 2);
		draw();

		while (playing)
		{
			while (shownCards.size() < 2)
			{
				Console::gotoxy(x * 4 + 2, y * 2 + 1);
				char input = _getch();
				switch (input)
				{
				case KEY_UP:
					if (y > 0)
						y--;
					break;
				case KEY_RIGHT:
					if (x < (*cvv)[0].size() - 1)
						x++;
					break;
				case KEY_DOWN:
					if (y < (*cvv).size() - 1)
						y++;
					break;
				case KEY_LEFT:
					if (x > 0)
						x--;
					break;
				case KEY_ENTER:
					if (!((*cvv)[y][x].isFlipped()) && !((*cvv)[y][x].isTaken()))
					{
						(*cvv)[y][x].setFlipped(true);
						shownCards.push_back(&((*cvv)[y][x]));
						draw();
					}
					break;
				default:
					break;
				}
			}
			Sleep(850);

			if (shownCards[0]->getSymbol() == shownCards[1]->getSymbol())
			{
				pv[currentPlayer].setScore( pv[currentPlayer].getScore() + 10 );
				shownCards[0]->setTaken(true);
				shownCards[1]->setTaken(true);

				//check if all cards are taken
				playing = false;
				for (int i = 0; i < (*cvv).size(); i++)
				{
					for (int j = 0; j < (*cvv)[i].size(); j++)
					{
						if ((*cvv)[i][j].isTaken() == false)
							playing = true;
					}
				}
			}
			else
			{
				shownCards[0]->setFlipped(false);
				shownCards[1]->setFlipped(false);
				if (currentPlayer < pv.size() - 1)
					currentPlayer++;
				else
					currentPlayer = 0;
			}
			shownCards.clear();

			draw();
		}
		cout << endl << endl;
		cout << "Winner ";
		int winner = 0;
		for (int i = 1; i < pv.size(); i++){
			if (pv[winner].getScore() < pv[i].getScore()){
				winner = i;
			}
		}
		cout << pv[winner].getName() << "!" << endl;
		highScore h1;
		h1.read();
		h1.add(pv[winner].getName(), pv[winner].getScore());
		h1.write();
		system("pause");
	}



	//constructors
	memory::memory()		//default constructor, 12-card memory board with 2 players
	{
		create_players(2);
		create_board(3, 4);
	}

	memory::memory(int p, int r, int c){
		create_players(p);
		create_board(r, c);
	}

	//destructors
	memory::~memory()
	{
		delete cvv;
	}

}